//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension Evs {
    // MARK: Enums

    public enum CheckResult: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case failed = "FAILED"
        case passed = "PASSED"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum CheckType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case hostCount = "HOST_COUNT"
        case keyCoverage = "KEY_COVERAGE"
        case keyReuse = "KEY_REUSE"
        case reachability = "REACHABILITY"
        public var description: String { return self.rawValue }
    }

    public enum EnvironmentState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case createFailed = "CREATE_FAILED"
        case created = "CREATED"
        case creating = "CREATING"
        case deleted = "DELETED"
        case deleting = "DELETING"
        public var description: String { return self.rawValue }
    }

    public enum HostState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case createFailed = "CREATE_FAILED"
        case created = "CREATED"
        case creating = "CREATING"
        case deleted = "DELETED"
        case deleting = "DELETING"
        case updateFailed = "UPDATE_FAILED"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum InstanceType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case i4iMetal = "i4i.metal"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cannotParse = "cannotParse"
        case fieldValidationFailed = "fieldValidationFailed"
        case other = "other"
        case unknownOperation = "unknownOperation"
        public var description: String { return self.rawValue }
    }

    public enum VcfVersion: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case vcf521 = "VCF-5.2.1"
        public var description: String { return self.rawValue }
    }

    public enum VlanState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case createFailed = "CREATE_FAILED"
        case created = "CREATED"
        case creating = "CREATING"
        case deleted = "DELETED"
        case deleting = "DELETING"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct Check: AWSDecodableShape {
        /// The time when environment health began to be impaired.
        public let impairedSince: Date?
        ///  The check result.
        public let result: CheckResult?
        /// The check type. Amazon EVS performs the following checks.    KEY_REUSE: checks that the VCF license key is not used by another Amazon EVS environment. This check fails if a used license is added to the environment.    KEY_COVERAGE: checks that your VCF license key allocates sufficient vCPU cores for all deployed hosts. The check fails when any assigned hosts in the EVS environment are not covered by license keys, or when any unassigned hosts cannot be covered by available vCPU cores in keys.    REACHABILITY: checks that the Amazon EVS control plane has a persistent connection to SDDC Manager. If Amazon EVS cannot reach the environment, this check fails.    HOST_COUNT: Checks that your environment has a minimum of 4 hosts, which is a requirement for VCF 5.2.1. If this check fails, you will need to add hosts so that your environment meets this minimum requirement. Amazon EVS only supports environments with 4-16 hosts.
        public let type: CheckType?

        @inlinable
        public init(impairedSince: Date? = nil, result: CheckResult? = nil, type: CheckType? = nil) {
            self.impairedSince = impairedSince
            self.result = result
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case impairedSince = "impairedSince"
            case result = "result"
            case type = "type"
        }
    }

    public struct ConnectivityInfo: AWSEncodableShape & AWSDecodableShape {
        /// The unique IDs for private route server peers.
        public let privateRouteServerPeerings: [String]

        @inlinable
        public init(privateRouteServerPeerings: [String]) {
            self.privateRouteServerPeerings = privateRouteServerPeerings
        }

        public func validate(name: String) throws {
            try self.privateRouteServerPeerings.forEach {
                try validate($0, name: "privateRouteServerPeerings[]", parent: name, max: 21)
                try validate($0, name: "privateRouteServerPeerings[]", parent: name, min: 3)
            }
            try self.validate(self.privateRouteServerPeerings, name: "privateRouteServerPeerings", parent: name, max: 2)
            try self.validate(self.privateRouteServerPeerings, name: "privateRouteServerPeerings", parent: name, min: 2)
        }

        private enum CodingKeys: String, CodingKey {
            case privateRouteServerPeerings = "privateRouteServerPeerings"
        }
    }

    public struct CreateEnvironmentHostRequest: AWSEncodableShape {
        ///  This parameter is not used in Amazon EVS currently. If you supply input for this parameter, it will have no effect.  A unique, case-sensitive identifier that you provide to ensure the idempotency of the host creation request. If you do not specify a client token, a randomly generated token is used for the request to ensure idempotency.
        public let clientToken: String?
        /// A unique ID for the environment that the host is added to.
        public let environmentId: String
        /// The host that is created and added to the environment.
        public let host: HostInfoForCreate

        @inlinable
        public init(clientToken: String? = CreateEnvironmentHostRequest.idempotencyToken(), environmentId: String, host: HostInfoForCreate) {
            self.clientToken = clientToken
            self.environmentId = environmentId
            self.host = host
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 100)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[!-~]+$")
            try self.validate(self.environmentId, name: "environmentId", parent: name, pattern: "^(env-[a-zA-Z0-9]{10})$")
            try self.host.validate(name: "\(name).host")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case environmentId = "environmentId"
            case host = "host"
        }
    }

    public struct CreateEnvironmentHostResponse: AWSDecodableShape {
        /// A summary of the environment that the host is created in.
        public let environmentSummary: EnvironmentSummary?
        /// A description of the created host.
        public let host: Host?

        @inlinable
        public init(environmentSummary: EnvironmentSummary? = nil, host: Host? = nil) {
            self.environmentSummary = environmentSummary
            self.host = host
        }

        private enum CodingKeys: String, CodingKey {
            case environmentSummary = "environmentSummary"
            case host = "host"
        }
    }

    public struct CreateEnvironmentRequest: AWSEncodableShape {
        ///  This parameter is not used in Amazon EVS currently. If you supply input for this parameter, it will have no effect.  A unique, case-sensitive identifier that you provide to ensure the idempotency of the environment creation request. If you do not specify a client token, a randomly generated token is used for the request to ensure idempotency.
        public let clientToken: String?
        ///  The connectivity configuration for the environment. Amazon EVS requires that you specify two route server peer IDs. During environment creation, the route server endpoints peer with the NSX edges over the NSX, providing BGP dynamic routing for overlay networks.
        public let connectivityInfo: ConnectivityInfo
        /// The name to give to your environment. The name can contain only alphanumeric characters (case-sensitive), hyphens, and underscores. It must start with an alphanumeric character, and can't be longer than 100 characters. The name must be unique within the Amazon Web Services Region and Amazon Web Services account that you're creating the environment in.
        public let environmentName: String?
        /// The ESXi hosts to add to the environment. Amazon EVS requires that you provide details for a minimum of 4 hosts during environment creation. For each host, you must provide the desired hostname, EC2 SSH key, and EC2 instance type. Optionally, you can also provide a partition or cluster placement group to use, or use Amazon EC2 Dedicated Hosts.
        public let hosts: [HostInfoForCreate]
        /// The initial VLAN subnets for the environment. You must specify a non-overlapping CIDR block for each VLAN subnet.
        public let initialVlans: InitialVlans
        /// A unique ID for the customer-managed KMS key that is used to encrypt the VCF credential pairs for SDDC Manager, NSX Manager, and vCenter appliances. These credentials are stored in Amazon Web Services Secrets Manager.
        public let kmsKeyId: String?
        /// The license information that Amazon EVS requires to create an environment. Amazon EVS requires two license keys: a VCF solution key and a vSAN license key. VCF licenses must have sufficient core entitlements to cover vCPU core and vSAN storage capacity needs. VCF licenses can be used for only one Amazon EVS environment. Amazon EVS does not support reuse of VCF licenses for multiple environments. VCF license information can be retrieved from the Broadcom portal.
        public let licenseInfo: [LicenseInfo]
        /// The security group that controls communication between the Amazon EVS control plane and VPC. The default security group is used if a custom security group isn't specified. The security group should allow access to the following.   TCP/UDP access to the DNS servers   HTTPS/SSH access to the host management VLAN subnet   HTTPS/SSH access to the Management VM VLAN subnet   You should avoid modifying the security group rules after deployment, as this can break the persistent connection between the Amazon EVS control plane and VPC. This can cause future environment actions like adding or removing hosts to fail.
        public let serviceAccessSecurityGroups: ServiceAccessSecurityGroups?
        /// The subnet that is used to establish connectivity between the Amazon EVS control plane and VPC. Amazon EVS uses this subnet to validate mandatory DNS records for your VCF appliances and hosts and create the environment.
        public let serviceAccessSubnetId: String
        /// The Broadcom Site ID that is allocated to you as part of your electronic software delivery. This ID allows customer access to the Broadcom portal, and is provided to you by Broadcom at the close of your software contract or contract renewal. Amazon EVS uses the Broadcom Site ID that you provide to meet Broadcom VCF license usage reporting requirements for Amazon EVS.
        public let siteId: String
        /// Metadata that assists with categorization and organization. Each tag consists of a key and an optional value. You define both. Tags don't propagate to any other cluster or Amazon Web Services resources.
        public let tags: [String: String]?
        /// Customer confirmation that the customer has purchased and maintains sufficient VCF software licenses to cover all physical processor cores in the environment, in compliance with VMware's licensing requirements and terms of use.
        public let termsAccepted: Bool
        /// The DNS hostnames for the virtual machines that host the VCF management appliances. Amazon EVS requires that you provide DNS hostnames for the following appliances: vCenter, NSX Manager, SDDC Manager, and Cloud Builder.
        public let vcfHostnames: VcfHostnames
        ///  The VCF version to use for the environment. Amazon EVS only supports VCF version 5.2.1 at this time.
        public let vcfVersion: VcfVersion
        /// A unique ID for the VPC that connects to the environment control plane for service access. Amazon EVS requires that all VPC subnets exist in a single Availability Zone in a Region where the service is available. The VPC that you select must have a valid DHCP option set with domain name, at least two DNS servers, and an NTP server. These settings are used to configure your VCF appliances and hosts. If you plan to use HCX over the internet, choose a VPC that has a primary CIDR block and a /28 secondary CIDR block from an IPAM pool. Make sure that your VPC also has an attached internet gateway. Amazon EVS does not support the following Amazon Web Services networking options for NSX overlay connectivity: cross-Region VPC peering, Amazon S3 gateway endpoints, or Amazon Web Services Direct Connect virtual private gateway associations.
        public let vpcId: String

        @inlinable
        public init(clientToken: String? = CreateEnvironmentRequest.idempotencyToken(), connectivityInfo: ConnectivityInfo, environmentName: String? = nil, hosts: [HostInfoForCreate], initialVlans: InitialVlans, kmsKeyId: String? = nil, licenseInfo: [LicenseInfo], serviceAccessSecurityGroups: ServiceAccessSecurityGroups? = nil, serviceAccessSubnetId: String, siteId: String, tags: [String: String]? = nil, termsAccepted: Bool, vcfHostnames: VcfHostnames, vcfVersion: VcfVersion, vpcId: String) {
            self.clientToken = clientToken
            self.connectivityInfo = connectivityInfo
            self.environmentName = environmentName
            self.hosts = hosts
            self.initialVlans = initialVlans
            self.kmsKeyId = kmsKeyId
            self.licenseInfo = licenseInfo
            self.serviceAccessSecurityGroups = serviceAccessSecurityGroups
            self.serviceAccessSubnetId = serviceAccessSubnetId
            self.siteId = siteId
            self.tags = tags
            self.termsAccepted = termsAccepted
            self.vcfHostnames = vcfHostnames
            self.vcfVersion = vcfVersion
            self.vpcId = vpcId
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 100)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[!-~]+$")
            try self.connectivityInfo.validate(name: "\(name).connectivityInfo")
            try self.validate(self.environmentName, name: "environmentName", parent: name, max: 100)
            try self.validate(self.environmentName, name: "environmentName", parent: name, min: 1)
            try self.validate(self.environmentName, name: "environmentName", parent: name, pattern: "^[a-zA-Z0-9_-]+$")
            try self.hosts.forEach {
                try $0.validate(name: "\(name).hosts[]")
            }
            try self.validate(self.hosts, name: "hosts", parent: name, max: 4)
            try self.validate(self.hosts, name: "hosts", parent: name, min: 4)
            try self.initialVlans.validate(name: "\(name).initialVlans")
            try self.licenseInfo.forEach {
                try $0.validate(name: "\(name).licenseInfo[]")
            }
            try self.validate(self.licenseInfo, name: "licenseInfo", parent: name, max: 1)
            try self.validate(self.licenseInfo, name: "licenseInfo", parent: name, min: 1)
            try self.serviceAccessSecurityGroups?.validate(name: "\(name).serviceAccessSecurityGroups")
            try self.validate(self.serviceAccessSubnetId, name: "serviceAccessSubnetId", parent: name, max: 24)
            try self.validate(self.serviceAccessSubnetId, name: "serviceAccessSubnetId", parent: name, min: 15)
            try self.validate(self.serviceAccessSubnetId, name: "serviceAccessSubnetId", parent: name, pattern: "^subnet-[a-f0-9]{8}([a-f0-9]{9})?$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^[\\w.:/=+-@]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^[\\w.:/=+-@]+|$")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.vcfHostnames.validate(name: "\(name).vcfHostnames")
            try self.validate(self.vpcId, name: "vpcId", parent: name, max: 21)
            try self.validate(self.vpcId, name: "vpcId", parent: name, min: 12)
            try self.validate(self.vpcId, name: "vpcId", parent: name, pattern: "^vpc-[a-f0-9]{8}([a-f0-9]{9})?$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case connectivityInfo = "connectivityInfo"
            case environmentName = "environmentName"
            case hosts = "hosts"
            case initialVlans = "initialVlans"
            case kmsKeyId = "kmsKeyId"
            case licenseInfo = "licenseInfo"
            case serviceAccessSecurityGroups = "serviceAccessSecurityGroups"
            case serviceAccessSubnetId = "serviceAccessSubnetId"
            case siteId = "siteId"
            case tags = "tags"
            case termsAccepted = "termsAccepted"
            case vcfHostnames = "vcfHostnames"
            case vcfVersion = "vcfVersion"
            case vpcId = "vpcId"
        }
    }

    public struct CreateEnvironmentResponse: AWSDecodableShape {
        /// A description of the created environment.
        public let environment: Environment?

        @inlinable
        public init(environment: Environment? = nil) {
            self.environment = environment
        }

        private enum CodingKeys: String, CodingKey {
            case environment = "environment"
        }
    }

    public struct DeleteEnvironmentHostRequest: AWSEncodableShape {
        ///  This parameter is not used in Amazon EVS currently. If you supply input for this parameter, it will have no effect.  A unique, case-sensitive identifier that you provide to ensure the idempotency of the host deletion request. If you do not specify a client token, a randomly generated token is used for the request to ensure idempotency.
        public let clientToken: String?
        /// A unique ID for the host's environment.
        public let environmentId: String
        /// The DNS hostname associated with the host to be deleted.
        public let hostName: String

        @inlinable
        public init(clientToken: String? = DeleteEnvironmentHostRequest.idempotencyToken(), environmentId: String, hostName: String) {
            self.clientToken = clientToken
            self.environmentId = environmentId
            self.hostName = hostName
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 100)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[!-~]+$")
            try self.validate(self.environmentId, name: "environmentId", parent: name, pattern: "^(env-[a-zA-Z0-9]{10})$")
            try self.validate(self.hostName, name: "hostName", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
            case environmentId = "environmentId"
            case hostName = "hostName"
        }
    }

    public struct DeleteEnvironmentHostResponse: AWSDecodableShape {
        /// A summary of the environment that the host was deleted from.
        public let environmentSummary: EnvironmentSummary?
        /// A description of the deleted host.
        public let host: Host?

        @inlinable
        public init(environmentSummary: EnvironmentSummary? = nil, host: Host? = nil) {
            self.environmentSummary = environmentSummary
            self.host = host
        }

        private enum CodingKeys: String, CodingKey {
            case environmentSummary = "environmentSummary"
            case host = "host"
        }
    }

    public struct DeleteEnvironmentRequest: AWSEncodableShape {
        ///  This parameter is not used in Amazon EVS currently. If you supply input for this parameter, it will have no effect.  A unique, case-sensitive identifier that you provide to ensure the idempotency of the environment deletion request. If you do not specify a client token, a randomly generated token is used for the request to ensure idempotency.
        public let clientToken: String?
        /// A unique ID associated with the environment to be deleted.
        public let environmentId: String

        @inlinable
        public init(clientToken: String? = DeleteEnvironmentRequest.idempotencyToken(), environmentId: String) {
            self.clientToken = clientToken
            self.environmentId = environmentId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.clientToken, forKey: .clientToken)
            request.encodePath(self.environmentId, key: "environmentId")
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 100)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[!-~]+$")
            try self.validate(self.environmentId, name: "environmentId", parent: name, pattern: "^(env-[a-zA-Z0-9]{10})$")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "clientToken"
        }
    }

    public struct DeleteEnvironmentResponse: AWSDecodableShape {
        /// A description of the deleted environment.
        public let environment: Environment?

        @inlinable
        public init(environment: Environment? = nil) {
            self.environment = environment
        }

        private enum CodingKeys: String, CodingKey {
            case environment = "environment"
        }
    }

    public struct Environment: AWSDecodableShape {
        /// A check on the environment to identify instance health and VMware VCF licensing issues.
        public let checks: [Check]?
        /// The connectivity configuration for the environment. Amazon EVS requires that you specify two route server peer IDs. During environment creation, the route server endpoints peer with the NSX uplink VLAN for connectivity to the NSX overlay network.
        public let connectivityInfo: ConnectivityInfo?
        /// The date and time that the environment was created.
        public let createdAt: Date?
        /// The VCF credentials that are stored as Amazon EVS managed secrets in Amazon Web Services Secrets Manager. Amazon EVS stores credentials that are needed to install vCenter Server, NSX, and SDDC Manager.
        public let credentials: [Secret]?
        /// The Amazon Resource Name (ARN) that is associated with the environment.
        public let environmentArn: String?
        /// The unique ID for the environment.
        public let environmentId: String?
        /// The name of the environment.
        public let environmentName: String?
        /// The state of an environment.
        public let environmentState: EnvironmentState?
        /// Reports impaired functionality that stems from issues internal to the environment, such as impaired reachability.
        public let environmentStatus: CheckResult?
        /// The Amazon Web Services KMS key ID that Amazon Web Services Secrets Manager uses to encrypt secrets that are associated with the environment. These secrets contain the VCF credentials that are needed to install vCenter Server, NSX, and SDDC Manager. By default, Amazon EVS use the Amazon Web Services Secrets Manager managed key aws/secretsmanager. You can also specify a customer managed key.
        public let kmsKeyId: String?
        ///  The license information that Amazon EVS requires to create an environment. Amazon EVS requires two license keys: a VCF solution key and a vSAN license key.
        public let licenseInfo: [LicenseInfo]?
        ///  The date and time that the environment was modified.
        public let modifiedAt: Date?
        /// The security groups that allow traffic between the Amazon EVS control plane and your VPC for service access. If a security group is not specified, Amazon EVS uses the default security group in your account for service access.
        public let serviceAccessSecurityGroups: ServiceAccessSecurityGroups?
        ///  The subnet that is used to establish connectivity between the Amazon EVS control plane and VPC. Amazon EVS uses this subnet to perform validations and create the environment.
        public let serviceAccessSubnetId: String?
        /// The Broadcom Site ID that is associated with your Amazon EVS environment. Amazon EVS uses the Broadcom Site ID that you provide to meet Broadcom VCF license usage reporting requirements for Amazon EVS.
        public let siteId: String?
        /// A detailed description of the environmentState of an environment.
        public let stateDetails: String?
        /// Customer confirmation that the customer has purchased and maintains sufficient VCF software licenses to cover all physical processor cores in the environment, in compliance with VMware's licensing requirements and terms of use.
        public let termsAccepted: Bool?
        /// The DNS hostnames to be used by the VCF management appliances in your environment. For environment creation to be successful, each hostname entry must resolve to a domain name that you've registered in your DNS service of choice and configured in the DHCP option set of your VPC. DNS hostnames cannot be changed after environment creation has started.
        public let vcfHostnames: VcfHostnames?
        /// The VCF version of the environment.
        public let vcfVersion: VcfVersion?
        /// The VPC associated with the environment.
        public let vpcId: String?

        @inlinable
        public init(checks: [Check]? = nil, connectivityInfo: ConnectivityInfo? = nil, createdAt: Date? = nil, credentials: [Secret]? = nil, environmentArn: String? = nil, environmentId: String? = nil, environmentName: String? = nil, environmentState: EnvironmentState? = nil, environmentStatus: CheckResult? = nil, kmsKeyId: String? = nil, licenseInfo: [LicenseInfo]? = nil, modifiedAt: Date? = nil, serviceAccessSecurityGroups: ServiceAccessSecurityGroups? = nil, serviceAccessSubnetId: String? = nil, siteId: String? = nil, stateDetails: String? = nil, termsAccepted: Bool? = nil, vcfHostnames: VcfHostnames? = nil, vcfVersion: VcfVersion? = nil, vpcId: String? = nil) {
            self.checks = checks
            self.connectivityInfo = connectivityInfo
            self.createdAt = createdAt
            self.credentials = credentials
            self.environmentArn = environmentArn
            self.environmentId = environmentId
            self.environmentName = environmentName
            self.environmentState = environmentState
            self.environmentStatus = environmentStatus
            self.kmsKeyId = kmsKeyId
            self.licenseInfo = licenseInfo
            self.modifiedAt = modifiedAt
            self.serviceAccessSecurityGroups = serviceAccessSecurityGroups
            self.serviceAccessSubnetId = serviceAccessSubnetId
            self.siteId = siteId
            self.stateDetails = stateDetails
            self.termsAccepted = termsAccepted
            self.vcfHostnames = vcfHostnames
            self.vcfVersion = vcfVersion
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case checks = "checks"
            case connectivityInfo = "connectivityInfo"
            case createdAt = "createdAt"
            case credentials = "credentials"
            case environmentArn = "environmentArn"
            case environmentId = "environmentId"
            case environmentName = "environmentName"
            case environmentState = "environmentState"
            case environmentStatus = "environmentStatus"
            case kmsKeyId = "kmsKeyId"
            case licenseInfo = "licenseInfo"
            case modifiedAt = "modifiedAt"
            case serviceAccessSecurityGroups = "serviceAccessSecurityGroups"
            case serviceAccessSubnetId = "serviceAccessSubnetId"
            case siteId = "siteId"
            case stateDetails = "stateDetails"
            case termsAccepted = "termsAccepted"
            case vcfHostnames = "vcfHostnames"
            case vcfVersion = "vcfVersion"
            case vpcId = "vpcId"
        }
    }

    public struct EnvironmentSummary: AWSDecodableShape {
        ///  The date and time that the environment was created.
        public let createdAt: Date?
        /// The Amazon Resource Name (ARN) that is associated with the environment.
        public let environmentArn: String?
        /// A unique ID for the environment.
        public let environmentId: String?
        ///  The name of the environment.
        public let environmentName: String?
        /// The state of an environment.
        public let environmentState: EnvironmentState?
        /// Reports impaired functionality that stems from issues internal to the environment, such as impaired reachability.
        public let environmentStatus: CheckResult?
        ///  The date and time that the environment was modified.
        public let modifiedAt: Date?
        /// The VCF version of the environment.
        public let vcfVersion: VcfVersion?

        @inlinable
        public init(createdAt: Date? = nil, environmentArn: String? = nil, environmentId: String? = nil, environmentName: String? = nil, environmentState: EnvironmentState? = nil, environmentStatus: CheckResult? = nil, modifiedAt: Date? = nil, vcfVersion: VcfVersion? = nil) {
            self.createdAt = createdAt
            self.environmentArn = environmentArn
            self.environmentId = environmentId
            self.environmentName = environmentName
            self.environmentState = environmentState
            self.environmentStatus = environmentStatus
            self.modifiedAt = modifiedAt
            self.vcfVersion = vcfVersion
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "createdAt"
            case environmentArn = "environmentArn"
            case environmentId = "environmentId"
            case environmentName = "environmentName"
            case environmentState = "environmentState"
            case environmentStatus = "environmentStatus"
            case modifiedAt = "modifiedAt"
            case vcfVersion = "vcfVersion"
        }
    }

    public struct GetEnvironmentRequest: AWSEncodableShape {
        /// A unique ID for the environment.
        public let environmentId: String

        @inlinable
        public init(environmentId: String) {
            self.environmentId = environmentId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.environmentId, key: "environmentId")
        }

        public func validate(name: String) throws {
            try self.validate(self.environmentId, name: "environmentId", parent: name, pattern: "^(env-[a-zA-Z0-9]{10})$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetEnvironmentResponse: AWSDecodableShape {
        /// A description of the requested environment.
        public let environment: Environment?

        @inlinable
        public init(environment: Environment? = nil) {
            self.environment = environment
        }

        private enum CodingKeys: String, CodingKey {
            case environment = "environment"
        }
    }

    public struct Host: AWSDecodableShape {
        ///  The date and time that the host was created.
        public let createdAt: Date?
        /// The unique ID of the Amazon EC2 Dedicated Host.
        public let dedicatedHostId: String?
        /// The unique ID of the EC2 instance that represents the host.
        public let ec2InstanceId: String?
        /// The DNS hostname of the host. DNS hostnames for hosts must be unique across Amazon EVS environments and within VCF.
        public let hostName: String?
        ///  The state of the host.
        public let hostState: HostState?
        /// The EC2 instance type of the host.  EC2 instances created through Amazon EVS do not support associating an IAM instance profile.
        public let instanceType: InstanceType?
        /// The IP address of the host.
        public let ipAddress: String?
        /// The name of the SSH key that is used to access the host.
        public let keyName: String?
        ///  The date and time that the host was modified.
        public let modifiedAt: Date?
        /// The elastic network interfaces that are attached to the host.
        public let networkInterfaces: [NetworkInterface]?
        /// The unique ID of the placement group where the host is placed.
        public let placementGroupId: String?
        ///  A detailed description of the hostState of a host.
        public let stateDetails: String?

        @inlinable
        public init(createdAt: Date? = nil, dedicatedHostId: String? = nil, ec2InstanceId: String? = nil, hostName: String? = nil, hostState: HostState? = nil, instanceType: InstanceType? = nil, ipAddress: String? = nil, keyName: String? = nil, modifiedAt: Date? = nil, networkInterfaces: [NetworkInterface]? = nil, placementGroupId: String? = nil, stateDetails: String? = nil) {
            self.createdAt = createdAt
            self.dedicatedHostId = dedicatedHostId
            self.ec2InstanceId = ec2InstanceId
            self.hostName = hostName
            self.hostState = hostState
            self.instanceType = instanceType
            self.ipAddress = ipAddress
            self.keyName = keyName
            self.modifiedAt = modifiedAt
            self.networkInterfaces = networkInterfaces
            self.placementGroupId = placementGroupId
            self.stateDetails = stateDetails
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "createdAt"
            case dedicatedHostId = "dedicatedHostId"
            case ec2InstanceId = "ec2InstanceId"
            case hostName = "hostName"
            case hostState = "hostState"
            case instanceType = "instanceType"
            case ipAddress = "ipAddress"
            case keyName = "keyName"
            case modifiedAt = "modifiedAt"
            case networkInterfaces = "networkInterfaces"
            case placementGroupId = "placementGroupId"
            case stateDetails = "stateDetails"
        }
    }

    public struct HostInfoForCreate: AWSEncodableShape {
        /// The unique ID of the Amazon EC2 Dedicated Host.
        public let dedicatedHostId: String?
        /// The DNS hostname of the host. DNS hostnames for hosts must be unique across Amazon EVS environments and within VCF.
        public let hostName: String
        /// The EC2 instance type that represents the host.
        public let instanceType: InstanceType
        /// The name of the SSH key that is used to access the host.
        public let keyName: String
        /// The unique ID of the placement group where the host is placed.
        public let placementGroupId: String?

        @inlinable
        public init(dedicatedHostId: String? = nil, hostName: String, instanceType: InstanceType, keyName: String, placementGroupId: String? = nil) {
            self.dedicatedHostId = dedicatedHostId
            self.hostName = hostName
            self.instanceType = instanceType
            self.keyName = keyName
            self.placementGroupId = placementGroupId
        }

        public func validate(name: String) throws {
            try self.validate(self.dedicatedHostId, name: "dedicatedHostId", parent: name, max: 25)
            try self.validate(self.dedicatedHostId, name: "dedicatedHostId", parent: name, min: 1)
            try self.validate(self.dedicatedHostId, name: "dedicatedHostId", parent: name, pattern: "^h-[a-f0-9]{8}([a-f0-9]{9})?$")
            try self.validate(self.hostName, name: "hostName", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.keyName, name: "keyName", parent: name, max: 255)
            try self.validate(self.keyName, name: "keyName", parent: name, min: 1)
            try self.validate(self.keyName, name: "keyName", parent: name, pattern: "^[a-zA-Z0-9_-]+$")
            try self.validate(self.placementGroupId, name: "placementGroupId", parent: name, max: 25)
            try self.validate(self.placementGroupId, name: "placementGroupId", parent: name, min: 1)
            try self.validate(self.placementGroupId, name: "placementGroupId", parent: name, pattern: "^pg-[a-f0-9]{8}([a-f0-9]{9})?$")
        }

        private enum CodingKeys: String, CodingKey {
            case dedicatedHostId = "dedicatedHostId"
            case hostName = "hostName"
            case instanceType = "instanceType"
            case keyName = "keyName"
            case placementGroupId = "placementGroupId"
        }
    }

    public struct InitialVlanInfo: AWSEncodableShape {
        ///  The CIDR block that you provide to create a VLAN subnet. VLAN CIDR blocks must not overlap with other subnets in the VPC.
        public let cidr: String

        @inlinable
        public init(cidr: String) {
            self.cidr = cidr
        }

        public func validate(name: String) throws {
            try self.validate(self.cidr, name: "cidr", parent: name, pattern: "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/(3[0-2]|[1-2][0-9]|[0-9])$")
        }

        private enum CodingKeys: String, CodingKey {
            case cidr = "cidr"
        }
    }

    public struct InitialVlans: AWSEncodableShape {
        /// The edge VTEP VLAN subnet. This VLAN subnet manages traffic flowing between the internal network and external networks, including internet access and other site connections.
        public let edgeVTep: InitialVlanInfo
        /// An additional VLAN subnet that can be used to extend VCF capabilities once configured. For example, you can configure an expansion VLAN subnet to use NSX Federation for centralized management and synchronization of multiple NSX deployments across different locations.
        public let expansionVlan1: InitialVlanInfo
        /// An additional VLAN subnet that can be used to extend VCF capabilities once configured. For example, you can configure an expansion VLAN subnet to use NSX Federation for centralized management and synchronization of multiple NSX deployments across different locations.
        public let expansionVlan2: InitialVlanInfo
        /// The HCX VLAN subnet. This VLAN subnet allows the HCX Interconnnect (IX) and HCX Network Extension (NE) to reach their peers and enable HCX Service Mesh creation.
        public let hcx: InitialVlanInfo
        ///  The NSX uplink VLAN subnet. This VLAN subnet allows connectivity to the NSX overlay network.
        public let nsxUplink: InitialVlanInfo
        ///  The VMkernel management VLAN subnet. This VLAN subnet carries traffic for managing ESXi hosts and communicating with VMware vCenter Server.
        public let vmkManagement: InitialVlanInfo
        /// The VM management VLAN subnet. This VLAN subnet carries traffic for vSphere virtual machines.
        public let vmManagement: InitialVlanInfo
        ///  The vMotion VLAN subnet. This VLAN subnet carries traffic for vSphere vMotion.
        public let vMotion: InitialVlanInfo
        ///  The vSAN VLAN subnet. This VLAN subnet carries the communication between ESXi hosts to implement a vSAN shared storage pool.
        public let vSan: InitialVlanInfo
        ///  The VTEP VLAN subnet. This VLAN subnet handles internal network traffic between virtual machines within a VCF instance.
        public let vTep: InitialVlanInfo

        @inlinable
        public init(edgeVTep: InitialVlanInfo, expansionVlan1: InitialVlanInfo, expansionVlan2: InitialVlanInfo, hcx: InitialVlanInfo, nsxUplink: InitialVlanInfo, vmkManagement: InitialVlanInfo, vmManagement: InitialVlanInfo, vMotion: InitialVlanInfo, vSan: InitialVlanInfo, vTep: InitialVlanInfo) {
            self.edgeVTep = edgeVTep
            self.expansionVlan1 = expansionVlan1
            self.expansionVlan2 = expansionVlan2
            self.hcx = hcx
            self.nsxUplink = nsxUplink
            self.vmkManagement = vmkManagement
            self.vmManagement = vmManagement
            self.vMotion = vMotion
            self.vSan = vSan
            self.vTep = vTep
        }

        public func validate(name: String) throws {
            try self.edgeVTep.validate(name: "\(name).edgeVTep")
            try self.expansionVlan1.validate(name: "\(name).expansionVlan1")
            try self.expansionVlan2.validate(name: "\(name).expansionVlan2")
            try self.hcx.validate(name: "\(name).hcx")
            try self.nsxUplink.validate(name: "\(name).nsxUplink")
            try self.vmkManagement.validate(name: "\(name).vmkManagement")
            try self.vmManagement.validate(name: "\(name).vmManagement")
            try self.vMotion.validate(name: "\(name).vMotion")
            try self.vSan.validate(name: "\(name).vSan")
            try self.vTep.validate(name: "\(name).vTep")
        }

        private enum CodingKeys: String, CodingKey {
            case edgeVTep = "edgeVTep"
            case expansionVlan1 = "expansionVlan1"
            case expansionVlan2 = "expansionVlan2"
            case hcx = "hcx"
            case nsxUplink = "nsxUplink"
            case vmkManagement = "vmkManagement"
            case vmManagement = "vmManagement"
            case vMotion = "vMotion"
            case vSan = "vSan"
            case vTep = "vTep"
        }
    }

    public struct LicenseInfo: AWSEncodableShape & AWSDecodableShape {
        ///  The VCF solution key. This license unlocks VMware VCF product features, including vSphere, NSX, SDDC Manager, and vCenter Server.
        public let solutionKey: String
        ///  The VSAN license key. This license unlocks vSAN features.
        public let vsanKey: String

        @inlinable
        public init(solutionKey: String, vsanKey: String) {
            self.solutionKey = solutionKey
            self.vsanKey = vsanKey
        }

        public func validate(name: String) throws {
            try self.validate(self.solutionKey, name: "solutionKey", parent: name, pattern: "^[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}$")
            try self.validate(self.vsanKey, name: "vsanKey", parent: name, pattern: "^[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}$")
        }

        private enum CodingKeys: String, CodingKey {
            case solutionKey = "solutionKey"
            case vsanKey = "vsanKey"
        }
    }

    public struct ListEnvironmentHostsRequest: AWSEncodableShape {
        /// A unique ID for the environment.
        public let environmentId: String
        /// The maximum number of results to return. If you specify MaxResults in the request, the response includes information up to the limit specified.
        public let maxResults: Int?
        /// A unique pagination token for each page. If nextToken is returned, there are more results available. Make the call again using the returned token with all other arguments unchanged to retrieve the next page. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?

        @inlinable
        public init(environmentId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.environmentId = environmentId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.environmentId, key: "environmentId")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.environmentId, name: "environmentId", parent: name, pattern: "^(env-[a-zA-Z0-9]{10})$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListEnvironmentHostsResponse: AWSDecodableShape {
        /// A list of hosts in the environment.
        public let environmentHosts: [Host]?
        /// A unique pagination token for next page results. Make the call again using this token to retrieve the next page.
        public let nextToken: String?

        @inlinable
        public init(environmentHosts: [Host]? = nil, nextToken: String? = nil) {
            self.environmentHosts = environmentHosts
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case environmentHosts = "environmentHosts"
            case nextToken = "nextToken"
        }
    }

    public struct ListEnvironmentVlansRequest: AWSEncodableShape {
        /// A unique ID for the environment.
        public let environmentId: String
        /// The maximum number of results to return. If you specify MaxResults in the request, the response includes information up to the limit specified.
        public let maxResults: Int?
        /// A unique pagination token for each page. If nextToken is returned, there are more results available. Make the call again using the returned token with all other arguments unchanged to retrieve the next page. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?

        @inlinable
        public init(environmentId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.environmentId = environmentId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.environmentId, key: "environmentId")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        public func validate(name: String) throws {
            try self.validate(self.environmentId, name: "environmentId", parent: name, pattern: "^(env-[a-zA-Z0-9]{10})$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListEnvironmentVlansResponse: AWSDecodableShape {
        /// A list of VLANs that are associated with the specified environment.
        public let environmentVlans: [Vlan]?
        /// A unique pagination token for next page results. Make the call again using this token to retrieve the next page.
        public let nextToken: String?

        @inlinable
        public init(environmentVlans: [Vlan]? = nil, nextToken: String? = nil) {
            self.environmentVlans = environmentVlans
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case environmentVlans = "environmentVlans"
            case nextToken = "nextToken"
        }
    }

    public struct ListEnvironmentsRequest: AWSEncodableShape {
        /// The maximum number of results to return. If you specify MaxResults in the request, the response includes information up to the limit specified.
        public let maxResults: Int?
        /// A unique pagination token for each page. If nextToken is returned, there are more results available. Make the call again using the returned token with all other arguments unchanged to retrieve the next page. Each pagination token expires after 24 hours. Using an expired pagination token will return an HTTP 400 InvalidToken error.
        public let nextToken: String?
        /// The state of an environment. Used to filter response results to return only environments with the specified environmentState.
        public let state: [EnvironmentState]?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, state: [EnvironmentState]? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.state = state
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.state, key: "state")
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListEnvironmentsResponse: AWSDecodableShape {
        /// A list of environments with summarized environment details.
        public let environmentSummaries: [EnvironmentSummary]?
        /// A unique pagination token for next page results. Make the call again using this token to retrieve the next page.
        public let nextToken: String?

        @inlinable
        public init(environmentSummaries: [EnvironmentSummary]? = nil, nextToken: String? = nil) {
            self.environmentSummaries = environmentSummaries
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case environmentSummaries = "environmentSummaries"
            case nextToken = "nextToken"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) that identifies the resource to list tags for.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:evs:[a-z]{2}-[a-z]+-[0-9]:[0-9]{12}:environment/[a-zA-Z0-9_-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "resourceArn"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The tags for the resource.
        public let tags: [String: String]?

        @inlinable
        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct NetworkInterface: AWSDecodableShape {
        /// The unique ID of the elastic network interface.
        public let networkInterfaceId: String?

        @inlinable
        public init(networkInterfaceId: String? = nil) {
            self.networkInterfaceId = networkInterfaceId
        }

        private enum CodingKeys: String, CodingKey {
            case networkInterfaceId = "networkInterfaceId"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        /// Describes the error encountered.
        public let message: String
        /// The ID of the resource that could not be found.
        public let resourceId: String
        /// The type of the resource that is associated with the error.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct Secret: AWSDecodableShape {
        ///  The Amazon Resource Name (ARN) of the secret.
        public let secretArn: String?

        @inlinable
        public init(secretArn: String? = nil) {
            self.secretArn = secretArn
        }

        private enum CodingKeys: String, CodingKey {
            case secretArn = "secretArn"
        }
    }

    public struct ServiceAccessSecurityGroups: AWSEncodableShape & AWSDecodableShape {
        /// The security groups that allow service access.
        public let securityGroups: [String]?

        @inlinable
        public init(securityGroups: [String]? = nil) {
            self.securityGroups = securityGroups
        }

        public func validate(name: String) throws {
            try self.securityGroups?.forEach {
                try validate($0, name: "securityGroups[]", parent: name, max: 25)
                try validate($0, name: "securityGroups[]", parent: name, min: 3)
                try validate($0, name: "securityGroups[]", parent: name, pattern: "^sg-[0-9a-zA-Z]*$")
            }
            try self.validate(self.securityGroups, name: "securityGroups", parent: name, max: 2)
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroups = "securityGroups"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource to add tags to.
        public let resourceArn: String
        /// Metadata that assists with categorization and organization. Each tag consists of a key and an optional value. You define both. Tags don't propagate to any other environment or Amazon Web Services resources.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:evs:[a-z]{2}-[a-z]+-[0-9]:[0-9]{12}:environment/[a-zA-Z0-9_-]+$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.key, name: "tags.key", parent: name, pattern: "^[\\w.:/=+-@]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, pattern: "^[\\w.:/=+-@]+|$")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "resourceArn"
            case tags = "tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ThrottlingException: AWSErrorShape {
        /// Describes the error encountered.
        public let message: String
        /// The seconds to wait to retry.
        public let retryAfterSeconds: Int?

        @inlinable
        public init(message: String, retryAfterSeconds: Int? = nil) {
            self.message = message
            self.retryAfterSeconds = retryAfterSeconds
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decode(String.self, forKey: .message)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource to delete tags from.
        public let resourceArn: String
        /// The keys of the tags to delete.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:evs:[a-z]{2}-[a-z]+-[0-9]:[0-9]{12}:environment/[a-zA-Z0-9_-]+$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^[\\w.:/=+-@]+$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "resourceArn"
            case tagKeys = "tagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ValidationException: AWSErrorShape {
        /// A list of fields that didn't validate.
        public let fieldList: [ValidationExceptionField]?
        /// Describes the error encountered.
        public let message: String
        /// The reason for the exception.
        public let reason: ValidationExceptionReason

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String, reason: ValidationExceptionReason) {
            self.fieldList = fieldList
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        ///  A message describing why the field failed validation.
        public let message: String
        ///  The field name.
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }

    public struct VcfHostnames: AWSEncodableShape & AWSDecodableShape {
        /// The hostname for VMware Cloud Builder.
        public let cloudBuilder: String
        /// The VMware NSX hostname.
        public let nsx: String
        /// The hostname for the first NSX Edge node.
        public let nsxEdge1: String
        /// The hostname for the second NSX Edge node.
        public let nsxEdge2: String
        /// The hostname for the first VMware NSX Manager virtual machine (VM).
        public let nsxManager1: String
        /// The hostname for the second VMware NSX Manager virtual machine (VM).
        public let nsxManager2: String
        /// The hostname for the third VMware NSX Manager virtual machine (VM).
        public let nsxManager3: String
        /// The hostname for SDDC Manager.
        public let sddcManager: String
        /// The VMware vCenter hostname.
        public let vCenter: String

        @inlinable
        public init(cloudBuilder: String, nsx: String, nsxEdge1: String, nsxEdge2: String, nsxManager1: String, nsxManager2: String, nsxManager3: String, sddcManager: String, vCenter: String) {
            self.cloudBuilder = cloudBuilder
            self.nsx = nsx
            self.nsxEdge1 = nsxEdge1
            self.nsxEdge2 = nsxEdge2
            self.nsxManager1 = nsxManager1
            self.nsxManager2 = nsxManager2
            self.nsxManager3 = nsxManager3
            self.sddcManager = sddcManager
            self.vCenter = vCenter
        }

        public func validate(name: String) throws {
            try self.validate(self.cloudBuilder, name: "cloudBuilder", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.nsx, name: "nsx", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.nsxEdge1, name: "nsxEdge1", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.nsxEdge2, name: "nsxEdge2", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.nsxManager1, name: "nsxManager1", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.nsxManager2, name: "nsxManager2", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.nsxManager3, name: "nsxManager3", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.sddcManager, name: "sddcManager", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
            try self.validate(self.vCenter, name: "vCenter", parent: name, pattern: "^([a-zA-Z0-9\\-]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case cloudBuilder = "cloudBuilder"
            case nsx = "nsx"
            case nsxEdge1 = "nsxEdge1"
            case nsxEdge2 = "nsxEdge2"
            case nsxManager1 = "nsxManager1"
            case nsxManager2 = "nsxManager2"
            case nsxManager3 = "nsxManager3"
            case sddcManager = "sddcManager"
            case vCenter = "vCenter"
        }
    }

    public struct Vlan: AWSDecodableShape {
        /// The availability zone of the VLAN.
        public let availabilityZone: String?
        ///  The CIDR block of the VLAN.
        public let cidr: String?
        /// The date and time that the VLAN was created.
        public let createdAt: Date?
        /// The VMware VCF traffic type that is carried over the VLAN. For example, a VLAN with a functionName of hcx is being used to carry VMware HCX traffic.
        public let functionName: String?
        ///  The date and time that the VLAN was modified.
        public let modifiedAt: Date?
        /// The state details of the VLAN.
        public let stateDetails: String?
        ///  The unique ID of the VLAN subnet.
        public let subnetId: String?
        /// The unique ID of the VLAN.
        public let vlanId: Int?
        ///  The state of the VLAN.
        public let vlanState: VlanState?

        @inlinable
        public init(availabilityZone: String? = nil, cidr: String? = nil, createdAt: Date? = nil, functionName: String? = nil, modifiedAt: Date? = nil, stateDetails: String? = nil, subnetId: String? = nil, vlanId: Int? = nil, vlanState: VlanState? = nil) {
            self.availabilityZone = availabilityZone
            self.cidr = cidr
            self.createdAt = createdAt
            self.functionName = functionName
            self.modifiedAt = modifiedAt
            self.stateDetails = stateDetails
            self.subnetId = subnetId
            self.vlanId = vlanId
            self.vlanState = vlanState
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "availabilityZone"
            case cidr = "cidr"
            case createdAt = "createdAt"
            case functionName = "functionName"
            case modifiedAt = "modifiedAt"
            case stateDetails = "stateDetails"
            case subnetId = "subnetId"
            case vlanId = "vlanId"
            case vlanState = "vlanState"
        }
    }
}

// MARK: - Errors

/// Error enum for Evs
public struct EvsErrorType: AWSErrorType {
    enum Code: String {
        case resourceNotFoundException = "ResourceNotFoundException"
        case tagPolicyException = "TagPolicyException"
        case throttlingException = "ThrottlingException"
        case tooManyTagsException = "TooManyTagsException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Evs
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// A service resource associated with the request could not be found. The resource might not be specified correctly, or it may have a state of DELETED.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The request doesn't comply with IAM tag policy. Correct your request and then retry it.
    public static var tagPolicyException: Self { .init(.tagPolicyException) }
    /// The CreateEnvironmentHost operation couldn't be performed because the service is throttling requests. This exception is thrown when the CreateEnvironmentHost request exceeds concurrency of 1 transaction per second (TPS).
    public static var throttlingException: Self { .init(.throttlingException) }
    /// A service resource associated with the request has more than 200 tags.
    public static var tooManyTagsException: Self { .init(.tooManyTagsException) }
    /// The input fails to satisfy the specified constraints. You will see this exception if invalid inputs are provided for any of the Amazon EVS environment operations, or if a list operation is performed on an environment resource that is still initializing.
    public static var validationException: Self { .init(.validationException) }
}

extension EvsErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ResourceNotFoundException": Evs.ResourceNotFoundException.self,
        "ThrottlingException": Evs.ThrottlingException.self,
        "ValidationException": Evs.ValidationException.self
    ]
}

extension EvsErrorType: Equatable {
    public static func == (lhs: EvsErrorType, rhs: EvsErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension EvsErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
